<template>
    <div :class="['calender', `calender--${lookType}`]">

        <div class="calender__header">
            <div class="calender-date-active">
               {{ currentDate.date }}
            </div>
            
            <div class="calender-date-btn">
                <ul>
                    <li @click="handleShowLastMonth">上个月 </li>
                    <li @click="handleShowToday">今天 </li>
                    <li @click="handleShowNextMonth">下个月 </li>
                </ul>
            </div>
        </div>

        <div class="calender__content">
            <ul class="calender-week">
                <li v-for="(week, index) in formatWeekDesc" :key="index">{{ week }}</li>
            </ul>
            <ul class="calender-day">
                <li :class="[item.class, { active: nowDate == item.date }]" v-for="(item, index) in calendarData" :key="index" @click="handleDateChange(item)"> 
                    <div class="data">{{ item.fill }}</div>
                    <span :class="['state', `state--${ item.state }`]"></span>
                </li>
            </ul>
        </div>

    </div>
</template>

<script>
export default {
    components: {  },
    props: {  },
    data() {
        return {
            weekDesc: ['一', '二', '三', '四', '五', '六', '日'],

            nowDate: '',

            calendarData: [],

            year: 0, //当前日期年

            month: 0, //当前日期月数

            date: 0, //当前日期号数
            
            day: -1, //当前星期几

            currentDate: {
                icon: '',
                class: '',
                state: '',
                fill: '',
                date: ''
            }
        };
    },
    props: {
        lookType: {                             //  区分样式        border  background
            type: String,
            default: 'border',  
        },

        weekStart: {                            //  周开始时间   周日开始  false   周一开始   true
            type: Boolean,
            default: true
        },

        boxFill: {                              //  填充物  默认为上个月 / 下个月的数字
            type: String,
            default: ''
        },

        showButtton: {                          //  是否显示默认按钮
            type: Boolean,
            default: false,
        },

    },
    watch: {
        
    },
    computed: {
        formatWeekDesc() {
            return this.weekStart?['一', '二', '三', '四', '五', '六', '日']:['日', '一', '二', '三', '四', '五', '六']
        }
    },
    methods: {


        mergCalenderState(list) {
            if(!list || !list.length) return
            
            list.forEach(item => {
                let haveOne = this.calendarData.find(current => current.date == item.date)
                Object.assign(haveOne, item)
            })
        },



        //  获取当前时间
        getNow() {
            let now = new Date()
            this.year = +now.getFullYear()
            this.month = +now.getMonth() + 1
            this.date = +now.getDate()
            this.day = +now.getDay()

            this.nowDate = `${ this.year }-${ this.getMonthStrict(this.month) }-${ this.getMonthStrict(this.date) }`
        },

        //  得到当前年这个月分有多少天
        getMonthDays(M) {
            let day = new Date(this.year, M, 0).getDate() 
            return day;
        },

        //  获取当月第一天是周几开始的
        getMonthFirstDayWeek() {
            let firstDay = new Date(`${ this.year }-${ this.month }-01`).getDay(); 
            let nowDays = parseInt(firstDay);
            if(this.weekStart) {
                nowDays = nowDays == 0?6:nowDays - 1
            } 
            return nowDays
        },


        getMonthStrict(month) {
            return (month / 10) >= 1 ? month: `0${month}` 
        },


        getCalendarDate() {
            this.calendarData = []
            let nowDays = this.getMonthFirstDayWeek()
            // 获取这个月有几天
            let nowMonthDays = this.getMonthDays(this.month);
            // 上个月是几月
            let beforeMonth = this.month - 1 > 0 ? this.month - 1:12;
            //  下个月是几月
            let nextMonth = this.month + 1 > 12 ? 1:this.month + 1;
            //  上个月有几天
            let beforeMonthDays =  this.getMonthDays(beforeMonth);
            
            //   循环添加上一个月数据
            for (let i = 0; i < nowDays; i++) {
                let beforeDay = beforeMonthDays - nowDays + i + 1
                let obj = {
                    icon: '',
                    state: '',
                    class: 'before',
                    fill: this.boxFill? this.boxFill : beforeDay,
                    date: `${ this.year }-${ this.getMonthStrict(beforeMonth) }-${this.getMonthStrict(beforeDay)}`
                }
                this.calendarData.push(obj);
            }

            // 循环添加当月数据
            for (let j = 0; j < nowMonthDays; j++) {
                let obj = {
                    icon: '',
                    class: '',
                    state: '',
                    fill: j + 1,
                    date: `${ this.year }-${ this.getMonthStrict(this.month) }-${this.getMonthStrict(j + 1)}`
                }
                this.calendarData.push(obj);
            }

            // 循环添加下一个月数据
            if (this.calendarData.length % 7 !== 0) {
                let surplusDay = 7 - (this.calendarData.length % 7);
                for (let k = 0; k < surplusDay; k++) {
                    let obj = {
                        icon: '',
                        state: '',
                        class: 'after',
                        fill: this.boxFill? this.boxFill : k + 1,
                        date: `${ this.year }-${ this.getMonthStrict(nextMonth) }-${this.getMonthStrict(k + 1)}`
                    }
                    this.calendarData.push(obj);
                }
            }
        },


        handleDateChange(date) {
            this.currentDate = JSON.parse(JSON.stringify(date))
        },

        // 上个月可以外界调用
        handleShowLastMonth() {
            this.month--;
            if (this.month <= 0) {
                this.year--;
                this.month = 12;
            }
            this.getCalendarDate();
        },

        handleShowToday() {
            let now = new Date()
            this.year = +now.getFullYear()
            this.month = +now.getMonth() + 1
            this.getCalendarDate();
        },
        
        // 下个月可以外界调用
        handleShowNextMonth() {
            this.month++;
            if (this.month > 12) {
                this.year++;
                this.month = 1;
            }
            this.getCalendarDate();
        }
    },
    created() {
        this.getNow()

        this.getCalendarDate(); 

    },
    mounted() {

    },
};
</script>
<style lang="scss" scoped>

$el: 'calender';

$width: 400px;

.#{$el} {
    width: $width;
    position: relative;
    margin: 0 auto;
    margin-top: 50px;
    padding: 20px;

    &__header {
        width: 100%;
        position: relative;
        display: flex;
        padding-bottom: 20px;

        .calender-date-active {
            width: 100px;
            text-align: left;
            line-height: 42px;
            font-size: 14px;
        }

        .calender-date-btn {
            flex: 1;
            text-align: right;

            ul {
                display: flex;
                flex-direction: row-reverse;

                li {
                    padding: 10px 20px;
                    font-size: 14px;
                    line-height: 20px;
                    cursor: pointer
                }
            }
        }
    }

    &__content {
        .calender-week {
            display: flex;
            flex-direction: row;
            padding: 20px 0;

            li {
                flex: 1;
                text-align: center;
                font-weight: bold;
                font-size: 16px;
            }
        }

        .calender-day {
            display: flex;
            flex-direction: row;
            padding: 10px 0;
            font-size: 16px;
            flex-wrap: wrap;

            li {
                position: relative;
                width: 14.28%;
                padding: 10px 0px;
                display: flex;
                justify-content: center;
                align-items: center;
                cursor: pointer;

                .data {
                    width: 32px;
                    height: 32px;
                    line-height: 32px;
                    text-align: center;
                    border-radius: 50%;
                }

                .state {
                    position: absolute;
                    width: 6px;
                    height: 6px;
                    left: auto;
                    bottom: 10px;
                    border-radius: 50%;
                }
            }
        }
    }


    &--border {
        border: 1px solid #ddd;

        .#{$el}__header {
            border-bottom: 1px solid #ddd;

            .calender-date-btn {
                ul {
                    li {
                        border: 1px solid #ddd;
                    }
                }
            }
        }

        .#{$el}__content {
            .calender-day {
                li {
                    border: 1px solid #ddd;

                    &.before, &.after {
                        background-color: rgba(177, 177, 177, 0.16);
                    }   

                    &:hover {
                        border-color: #55B8F9;
                        color: #55B8F9;
                    }

                    &.active {
                        border-color: #55B8F9;
                        color: #55B8F9;
                    }
                }
            }
        }
    }   

    &--background {
        .#{$el}__header {
            .calender-date-btn {
                ul {
                    li {
                        background-color: #ddd;
                    }
                }
            }
        }

        .#{$el}__content {
            .calender-day {
                li {
                    
                    
                    &.before, &.after {
                        background-color: rgba(177, 177, 177, 0.16);
                    }   

                    &:hover {
                        .data {
                            background-color: #55B8F9;
                            color: #FFFFFF;
                        }
                    }

                    &.active {
                        .data {
                            background-color: #55B8F9;
                            color: #FFFFFF;
                        }
                    }
                }
            }
        }
    }
}
</style>
